'''
使用takagiabm内置的标准网格模型建立的生命游戏。
作者：侯展意
协议：木兰2.0
'''
import random
import numpy as np
import takagiabm as tak# 这是第一种导入的方式。其他示例中还有另一种导入风格，可以按照喜好选用。
def modelSetup(model):
    global density
    for x in range(model.width):
        for y in range(model.height):

            a=np.array((x,y))
            if(random.random()>1-density.value/100.0):# 将50%的单元格设置为生.其余可自行定义.
                model.grid.getCellByPos(a).setProperty('alive', True)
                model.grid.getCellByPos(a).setColor(tak.red)# 红色
            else:
                model.grid.getCellByPos(a).setProperty('alive', False)
                model.grid.getCellByPos(a).setColor(tak.black)# 设置为黑色.

def countAliveNeighbors(neighbors=[]):# 在外部定义函数也是可以的！
    count=0
    for n in neighbors:
        if(n.getTrait('alive')==True):
            count+=1
        else:
            continue
    return count

def cellStep(cell):
    global usegreen
    
    cell.model.startTiming('getNeighbors')

    neighbors=cell.getNeighbors()# 获取八个邻居
    cell.model.endTiming('getNeighbors')
    count=countAliveNeighbors(neighbors)
    if(count==3):
        
        cell.setTraitLater('alive',True)# 属性不会立即改变,会等到所有的cell都step完了之后再改变.
    elif(count==8):
        pass
    elif(count==2):
        pass
    else:  
        cell.setTraitLater('alive',False)


    if(cell.getTrait('alive')==True):
        cell.setColor(tak.red)
    else:
        cell.setColor(tak.black)

density=tak.Var('density',20,range=(0,1,100))#min,max,step，最小，最大和步长。
varList=[density]

tak.GridModel=tak.prepareModel(modelClass=tak.GridModel,
                              varList=varList, agentActivationPolicy='none', cellActivationPolicy='casual',
                              modelInitFunc=modelSetup, width=50, height=50,bgcolor=tak.black)
tak.Cell=tak.prepareCell(cellClass=tak.Cell,cellStepFunc=cellStep)

if __name__=="__main__":
    tak.simStart(__file__, tak.GridModel, noGUI=False, maxSteps=10)





